package com.stylefeng.guns.modular.pay.service.impl;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.google.common.base.Strings;
import com.stylefeng.guns.core.base.tips.SuccessTip;
import com.stylefeng.guns.core.util.DateUtil;
import com.stylefeng.guns.modular.pay.dao.AllinMchMapper;
import com.stylefeng.guns.modular.pay.dao.WithdrawApplyMapper;
import com.stylefeng.guns.modular.pay.dao.WithdrawOrderMapper;
import com.stylefeng.guns.modular.pay.dao.WithdrawtAccountMapper;
import com.stylefeng.guns.modular.pay.model.AllinMch;
import com.stylefeng.guns.modular.pay.model.WithdrawApply;
import com.stylefeng.guns.modular.pay.model.WithdrawOrder;
import com.stylefeng.guns.modular.pay.model.WithdrawtAccount;
import com.stylefeng.guns.modular.pay.payment.allin.common.api.ApiRsp;
import com.stylefeng.guns.modular.pay.payment.allin.common.api.RpcSingleTranxReq;
import com.stylefeng.guns.modular.pay.payment.allin.common.api.Transret;
import com.stylefeng.guns.modular.pay.payment.allin.common.core.config.Configuer;
import com.stylefeng.guns.modular.pay.payment.allin.common.entity.common.AipgRsp;
import com.stylefeng.guns.modular.pay.payment.allin.common.entity.rtrsp.TransRet;
import com.stylefeng.guns.modular.pay.payment.allin.common.exception.AllInPayBizException;
import com.stylefeng.guns.modular.pay.service.AllInPayService;
import com.stylefeng.guns.modular.pay.service.IWithdrawApplyService;
import com.stylefeng.guns.modular.pay.util.AmountUtils;

/**
 * <p>
 * 提现申请表 服务实现类
 * </p>
 *
 * @author stylefeng
 * @since 2018-09-11
 */
@Service
public class WithdrawApplyServiceImpl extends ServiceImpl<WithdrawApplyMapper, WithdrawApply> implements IWithdrawApplyService {
    private final static Logger logger = LoggerFactory.getLogger(WithdrawApplyServiceImpl.class);

	@Autowired
	private WithdrawApplyMapper withdrawApplyMapper;
	@Autowired
	private AllInPayService allInPayService;
	@Autowired
	private WithdrawtAccountMapper withdrawtAccountMapper;
	@Autowired
	private AllinMchMapper allinMchMapper;
	@Autowired
	private WithdrawOrderMapper withdrawOrderMapper;
	
	@Override
	public List<WithdrawApply> selectList(WithdrawApply apply) {
		EntityWrapper<WithdrawApply> wrapper = new EntityWrapper<>();
		if(!Strings.isNullOrEmpty(apply.getOutTradeNo())){
			wrapper.eq("out_trade_no", apply.getOutTradeNo());
		}
		if(!Strings.isNullOrEmpty(apply.getAccountName())){
			wrapper.eq("account_name", apply.getAccountName());
		}
		if(!Strings.isNullOrEmpty(apply.getAccountNo())){
			wrapper.and().eq("account_no", apply.getAccountNo());
		}
		if(apply.getStatus()!=null){
			wrapper.and().eq("status", apply.getStatus());
		}
		wrapper.orderBy("id", false);
		return withdrawApplyMapper.selectList(wrapper);
	}
	
	
	@Transactional
	@Override
	public Object audit(WithdrawApply withdrawApply) throws Exception {
    	WithdrawApply apply = withdrawApplyMapper.selectById(withdrawApply.getId());
    	apply.setAuditDate(new Date());
    	if(!Strings.isNullOrEmpty(withdrawApply.getAuditDesc())){
    		apply.setAuditDesc(withdrawApply.getAuditDesc());
    	}
    	apply.setStatus(withdrawApply.getStatus());
    	withdrawApplyMapper.updateById(apply);
//    	if(withdrawApply.getStatus()==1){//审核成功
//    		logger.info("打款开始#############");
//    		remittance(apply);
//    	}
		return new SuccessTip();
	}


	private WithdrawOrder createOrder(WithdrawApply apply,WithdrawtAccount account,RpcSingleTranxReq req ) {
	  	WithdrawOrder order = new WithdrawOrder();
    	order.setAccountName(account.getAccountName());
    	order.setAccountNo(account.getAccountNo());
    	order.setAccountProp(account.getAccountProp());
    	order.setAccountType(account.getAccountType());
    	order.setAmount(new BigDecimal(apply.getAmount()));
    	order.setBankCode(account.getBankCode());
    	order.setBatchId(DateUtil.getAllTime());
    	order.setChargeAmount(new BigDecimal(0));
    	order.setCity(account.getCity());
    	order.setCreateTime(new Date());
    	order.setCustUserId("");
    	order.setTel(account.getTel());
    	order.setSubmitTime(req.getSubmitTime());
    	order.setCvv2(account.getCvv2());
    	order.setIdNo(account.getIdNo());
    	order.setIdType(account.getIdType());
    	order.setOutTradeNo(apply.getOutTradeNo());
    	order.setPlatTradeNo(req.getReq_sn());
    	order.setRealAmount(new BigDecimal(apply.getAmount()));
    	order.setReceiveAmount(new BigDecimal(apply.getAmount()));
    	order.setRemark(apply.getSummary());
    	order.setStatus(2);
    	withdrawOrderMapper.insert(order);
		return order;
	}


	private RpcSingleTranxReq buildReq(WithdrawApply apply, WithdrawtAccount account) {
		RpcSingleTranxReq req = new RpcSingleTranxReq();
    	req.setAccountName(account.getAccountName());
    	req.setAccountNo(account.getAccountNo());
    	req.setAccountProp(account.getAccountProp());
    	req.setAccountType(account.getAccountType());
    	req.setAmount(AmountUtils.changeY2F(apply.getAmount()));
    	if(!Strings.isNullOrEmpty(account.getBankCode())){
    		req.setBankCode(account.getBankCode());
    	}
    	req.setCurrency("CNY");
    	if(account.getAccountType().equals("02")){
    	   	req.setCvv2(account.getCvv2());
    	   	req.setValidate(account.getValidate());
    	}
    	if(!Strings.isNullOrEmpty(account.getIdNo())){
    		req.setId(account.getIdNo());
    	}
    	if(!Strings.isNullOrEmpty(account.getIdType())){
    	 	req.setIdType(account.getIdType());
    	}
    	//请求号
    	String reqSn = Configuer.MERCHANTID+DateUtil.getAllTime();
    	req.setReq_sn(reqSn);
    	if(!Strings.isNullOrEmpty(apply.getSummary())){
    	 	req.setSummary(apply.getSummary());
    	}
    	if(!Strings.isNullOrEmpty(account.getTel())){
    		req.setTel(account.getTel());
    	}
    	req.setSubmitTime(DateUtil.getAllTime());
    	return req;
	}

	
	@Override
	public void remittance(Integer withdrawApplyId) {
		WithdrawApply apply = withdrawApplyMapper.selectById(withdrawApplyId);
		if(apply==null){
			throw new RuntimeException("请求记录不存在");
		}
		if(apply.getStatus()==3 || apply.getStatus()==4){
			throw new RuntimeException("已打款或打款中，不能重复打款");
		}
		//打款
    	WithdrawtAccount account = withdrawtAccountMapper.selectById(apply.getPkAccountId());
    	if(account==null){
    		throw new RuntimeException("打款账号为空");
    	}
    	RpcSingleTranxReq req = buildReq(apply,account);
    	//配置信息获取
    	AllinMch condition = new AllinMch();
    	condition.setStatus(1);
    	AllinMch config =allinMchMapper.selectOne(condition);
    	if(config==null){
    		throw new RuntimeException("渠道配置信息尚未配置");
    	}
    	//创建交易流水
    	WithdrawOrder order = createOrder(apply,account,req);
    	ApiRsp res = null;
    	try {
    		 res = allInPayService.singleTranx(req,config);
		} catch (AllInPayBizException e) {
			e.printStackTrace();
			throw new RuntimeException(e.getMsg());
		}
    	String headRetCode = res.getINFO().getRET_CODE();
		if ("0000".equals(headRetCode) ||"4000".equals(headRetCode)) {
			Transret ret =  res.getTRANSRET();
			String code = ret.getRET_CODE();
			if("0000".equals(code) || "4000".equals(code)){//状态（0-已创建 1-提交成功 2-打款中 3-打款成功 4-打款失败
				order.setId(order.getId());
				order.setStatus(3);
				order.setRetCode(code);
				order.setErrMsg(ret.getERR_MSG());
				order.setSettleDay(ret.getSETTLE_DAY());
				order.setUpdateTime(new Date());
				withdrawOrderMapper.updateById(order);
				//打款成功//0-提交审核中 1-已审核 2-审核失败,3-打款中，4-打款成功，5-打款失败
				apply.setStatus(4);
				withdrawApplyMapper.updateById(apply);
			}else if("2000".equals(headRetCode)||"2001".equals(headRetCode)||"2003".equals(headRetCode)
					||"2005".equals(headRetCode)||"2007".equals(headRetCode)||"2008".equals(headRetCode)){
				order.setStatus(2);
				order.setRetCode(code);
				order.setErrMsg(ret.getERR_MSG());
				order.setUpdateTime(new Date());
				withdrawOrderMapper.updateById(order);
				//打款中
				apply.setStatus(3);
				withdrawApplyMapper.updateById(apply);
			}else{
				order.setStatus(4);
				order.setRetCode(code);
				order.setErrMsg(ret.getERR_MSG());
				order.setUpdateTime(new Date());
				withdrawOrderMapper.updateById(order);
				//打款失败
				apply.setStatus(5);
				withdrawApplyMapper.updateById(apply);
			}
		}else if("2000".equals(headRetCode)||"2001".equals(headRetCode)||"2003".equals(headRetCode)
				||"2005".equals(headRetCode)||"2007".equals(headRetCode)||"2008".equals(headRetCode)){//处理中
			order.setStatus(2);
			order.setRetCode(headRetCode);
			order.setErrMsg(res.getINFO().getERR_MSG());
			order.setUpdateTime(new Date());
			withdrawOrderMapper.updateById(order);
			//打款中
			apply.setStatus(3);
			withdrawApplyMapper.updateById(apply);
		}else{//失败
			order.setStatus(4);
			order.setRetCode(headRetCode);
			order.setErrMsg(res.getINFO().getERR_MSG());
			order.setUpdateTime(new Date());
			withdrawOrderMapper.updateById(order);
			//打款失败
			apply.setStatus(5);
			withdrawApplyMapper.updateById(apply);
		}
	}

}
